home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-04-04 | 44.9 KB | 1,736 lines | [TEXT/MPS ] |
- (*
-
- © 1988, Apple Computer, Inc.
- All rights reserved.
-
- Window2.p: A HyperCard XCMD in MPW Pascal 2.0.2 by Joe Zuffoletto
- Version 1.0, 29 June 1988
-
- Form: window title,top,left,bottom,right
-
- Example: window "My Window",50,100,300,400
-
- Notes: Window puts up a standard document window with scroll bars.
- The window can be dragged, resized, zoomed, and closed.
-
- Command-W is supported for closing the window. Command-spacebar
- toggles the menubar on and off, as in HyperCard. If you
- try to draw the window's title bar off the screen or under
- the menubar, Window will abort with an error message. Error
- messages can be examined by looking at HyperCard's global
- variable "the result" after calling Window.
-
- Window is MultiFinder friendly and works with all
- versions of HyperCard through 1.2.1. It supports multiple
- displays on the Mac II as well.
-
- Window takes a snapshot of the HyperCard card window and
- displays it like a MacPaint document. You can scroll up
- and down, etc. This is just for demonstration and amusement.
- You must supply your own code for displaying whatever you
- want to display in the window.
-
- -----------------------------------------------------------------------------
-
- To compile and link this file using MPW Pascal 2.0.2, select the following lines
- and press ENTER:
-
- Pascal Window2.p
- link -o "Hard Disk":HyperCard:"HyperCard Stacks":Home ∂
- -rt XCMD=2000 -sn Main=Window ∂
- Window2.p.o {MPW}Libraries:Interface.o ∂
- {MPW}PLibraries:PasLib.o ∂
- -m ENTRYPOINT
-
- Use other link files as necessary.
-
- The above link directives install the XCMD resource into the Home stack. You
- can substitute the name of any stack you want; be sure to provide the
- correct pathname. Also, make sure the target stack already has a resource
- fork or it won't work. You can create an empty resource fork in a stack
- with ResEdit.
-
- -----------------------------------------------------------------------------
-
- *)
-
- {$R-}
-
- {$S Window}
-
- UNIT DummyUnit;
-
- INTERFACE
-
- USES MemTypes,QuickDraw,OSIntf,ToolIntf,PasLibIntf,HyperXCmd;
-
- PROCEDURE EntryPoint(paramPtr:XCmdPtr);
-
- IMPLEMENTATION
-
- TYPE Str31 = String[31];
-
- OffScrHandle = ^OffScrRecPtr; {Attach to refCon of a window}
- OffScrRecPtr = ^OffScrRecord;
- OffScrRecord = RECORD
- gPort: GrafPtr; {Offscreen GrafPort}
- docWidth: INTEGER; {Document's width in pixels}
- docHeight: INTEGER; {Document's height in pixels}
- blitRect: Rect; {'Window' onto O.G.}
- blitWidth: INTEGER; {Current width of O.G. 'window'}
- blitHeight: INTEGER; {Current height of O.G. 'window'}
- dhGraf: LONGINT; {Pixels scrolled horizontally}
- dvGraf: LONGINT; {Pixels scrolled vertically}
- END;
-
- ScrollHandle = ^ScrollPtr; {Attach to refCon of a scroll bar}
- ScrollPtr = ^ScrollRecord;
- ScrollRecord = RECORD
- heldDown: INTEGER; {See procedure MyScroll}
- goFast: BOOLEAN;
- END;
-
- PROCEDURE Window(paramPtr:XCmdPtr);FORWARD;
-
- PROCEDURE EntryPoint(paramPtr:XCmdPtr);
- BEGIN
- Window(paramPtr);
- END;
-
-
- FUNCTION Min(int1,int2:INTEGER): INTEGER;
-
- {Return the smaller of two integers.}
-
- BEGIN
- IF (int1 <= int2) THEN
- Min := int1
- ELSE
- Min := Int2;
- END; {Min}
-
-
- PROCEDURE InitBlit(theWindow:WindowPtr);
-
- {Initialize the blit rectangle so it is in the upper left
- corner of the offscreen bitmap and so it is the same size
- as the target window onscreen.}
-
- VAR
- myOffScrHandle: OffScrHandle;
-
- BEGIN
- myOffScrHandle := OffScrHandle(GetWRefCon(theWindow));
- MoveHHi(Handle(myOffScrHandle));
- HLock(Handle(myOffScrHandle));
- WITH myOffScrHandle^^ DO
- BEGIN
- dhGraf := 0;
- dvGraf := 0;
-
- {Make sure blit rectangle doesn't hang off edges of offscreen bitmap, just
- in case window is larger.}
-
- blitWidth := Min((theWindow^.portRect.right - 15 - theWindow^.portRect.left),docWidth);
- blitHeight := Min((theWindow^.portRect.bottom - 15 - theWindow^.portRect.top),docHeight);
- SetRect(blitRect,gPort^.portBits.bounds.left,
- gPort^.portBits.bounds.top,
- gPort^.portBits.bounds.left + blitWidth,
- gPort^.portBits.bounds.top + blitHeight);
- END;
- HUnlock(Handle(myOffScrHandle));
- END; {InitBlit}
-
-
- PROCEDURE InvalContents(theWindow:WindowPtr;theOldSize:Rect);
-
- {Perform "intelligent" window updating; i.e., if the window is
- grown, invalidate for the update event only the part that wasn't
- visible before.}
-
- VAR
- myOffScrHandle: OffScrHandle;
- myWindowRect,windowRect: Rect;
- tallRect,wideRect: Rect;
- hWhiteSpace,vWhiteSpace: INTEGER;
- hBlitOffset,vBlitOffset: INTEGER;
- myDocWidth,myDocHeight: INTEGER;
- newDhGraf,newDvGraf: LONGINT;
- tempDH,tempDV: LONGINT;
-
- BEGIN
- hBlitOffset := 0;
- vBlitOffset := 0;
- myWindowRect := theWindow^.portRect;
- myOffScrHandle := OffScrHandle(GetWRefCon(theWindow));
- MoveHHi(Handle(myOffScrHandle));
- HLock(Handle(myOffScrHandle));
- WITH myOffScrHandle^^ DO
- BEGIN
- tempDH := dhGraf;
- tempDV := dvGraf;
- myDocWidth := docWidth;
- myDocHeight := docHeight;
- END;
-
- {If we have scrolled to the bottom and/or right edges of the document and then
- grow the window, the document will "follow" the window so we don't just expose
- a lot of white space. The same thing will happen if we zoom the window to a
- larger size. In either case, we need to invalidate the entire content region.}
-
- {Is any white space being exposed in the horizontal direction?}
-
- hWhiteSpace := (myWindowRect.right - myWindowRect.left - 15) - (myDocWidth - tempDH);
- IF (hWhiteSpace > 0) THEN
- BEGIN
-
- {If so, how much?}
-
- newDhGraf := tempDH - hWhiteSpace;
-
- {Move the document that distance, but not beyond the point where its
- left edge is flush with the left edge of the window.}
-
- IF newDhGraf < 0 THEN
- newDhGraf := 0;
-
- {Adjust blit rectangle accordingly.}
-
- hBlitOffset := INTEGER(tempDH - newDhGraf);
- tempDH := newDhGraf;
- END; {IF hWhiteSpace}
-
- {Repeat for vertical direction.}
-
- vWhiteSpace := (myWindowRect.bottom - myWindowRect.top - 15) - (myDocHeight - tempDV);
- IF (vWhiteSpace > 0) THEN
- BEGIN
- newDvGraf := tempDV - vWhiteSpace;
- IF newDvGraf < 0 THEN
- newDvGraf := 0;
- vBlitOffset := INTEGER(tempDV - newDvGraf);
- tempDV := newDvGraf;
- END; {IF vWhiteSpace}
-
- {Save what we've learned to the data structure.}
-
- WITH myOffScrHandle^^ DO
- BEGIN
- dhGraf := tempDH;
- dvGraf := tempDV;
- blitWidth := Min((myWindowRect.right - myWindowRect.left - 15),
- (myDocWidth - dhGraf));
- blitHeight := Min((myWindowRect.bottom - myWindowRect.top - 15),
- (myDocHeight - dvGraf));
- SetRect(blitRect,blitRect.left - hBlitOffset,
- blitRect.top - vBlitOffset,
- blitRect.left + blitWidth - hBlitOffset,
- blitRect.top + blitHeight - vBlitOffset);
- blitWidth := blitRect.right - blitRect.left;
- blitHeight := blitRect.bottom - blitRect.top;
- END;
- HUnlock(Handle(myOffScrHandle));
-
- {If the document has followed the window, invalidate entire content
- region.}
-
- IF ((hBlitOffset <> 0) OR (vBlitOffset <> 0)) THEN
- BEGIN
- EraseRect(theWindow^.portRect);
- InvalRect(theWindow^.portRect);
- END
- ELSE
-
- {Otherwise invalidate only the new white space.}
-
- BEGIN
- SetRect(tallRect,theOldSize.right,
- theWindow^.portRect.top,
- theWindow^.portRect.right,
- theWindow^.portRect.bottom);
- SetRect(wideRect,theWindow^.portRect.left,
- theOldSize.bottom,
- theOldSize.right,
- theWindow^.portRect.bottom);
- EraseRect(tallRect);
- EraseRect(wideRect);
- InvalRect(tallRect);
- InvalRect(wideRect);
- END; {IF hBlitOffset}
- END; {InvalContents}
-
-
- PROCEDURE DrawContents(theWindow:WindowPtr);
-
- {Blasts contents of updated blit rectangle to screen.}
-
- VAR
- myWindowRect,windowRect: Rect;
- myOffScrHandle: OffScrHandle;
-
- BEGIN
- myOffScrHandle := OffScrHandle(GetWRefCon(theWindow));
- myWindowRect := theWindow^.portRect;
- MoveHHi(Handle(myOffScrHandle));
- HLock(Handle(myOffScrHandle));
- SetRect(windowRect,myWindowRect.left,
- myWindowRect.top,
- myWindowRect.left + myOffScrHandle^^.blitWidth,
- myWindowRect.top + myOffScrHandle^^.blitHeight);
- ClipRect(windowRect);
- CopyBits(myOffScrHandle^^.gPort^.portBits,theWindow^.portBits,
- myOffScrHandle^^.blitRect,windowRect,
- srcCopy,NIL);
- HUnlock(Handle(myOffScrHandle));
- END; {DrawContents}
-
-
- PROCEDURE ScrollContents(theWindow:WindowPtr;dh,dv:INTEGER);
-
- VAR
- myOffScrHandle: OffScrHandle;
- leftSpace,topSpace: INTEGER;
- rightSpace,bottomSpace: INTEGER;
-
- BEGIN
-
- { Calculate space between edges of blitRect and edges of the bitmap. }
-
- myOffScrHandle := OffScrHandle(GetWRefCon(theWindow));
- MoveHHi(Handle(myOffScrHandle));
- HLock(Handle(myOffScrHandle));
- WITH myOffScrHandle^^ DO
- BEGIN
- leftSpace := gPort^.portBits.bounds.left - blitRect.left;
- topSpace := gPort^.portBits.bounds.top - blitRect.top;
- rightSpace := gPort^.portBits.bounds.right - blitRect.right;
- bottomSpace := gPort^.portBits.bounds.bottom - blitRect.bottom;
- END;
-
- { Then move blitRect, but not past the edge of the bitmap. }
-
- IF (dv = 0) THEN
- IF (dh > 0) THEN {moving to the right}
- IF (rightSpace > dh) THEN
- OffsetRect(myOffScrHandle^^.blitRect,dh,dv)
- ELSE
- BEGIN
- dh := rightSpace;
- OffsetRect(myOffScrHandle^^.blitRect,dh,dv);
- END
- ELSE {moving to the left}
- IF (leftSpace > dh) THEN
- BEGIN
- dh := leftSpace;
- OffsetRect(myOffScrHandle^^.blitRect,dh,dv);
- END
- ELSE
- OffsetRect(myOffScrHandle^^.blitRect,dh,dv)
- ELSE IF (dv > 0) THEN {moving down}
- IF (bottomSpace > dv) THEN
- OffsetRect(myOffScrHandle^^.blitRect,dh,dv)
- ELSE
- BEGIN
- dv := bottomSpace;
- OffsetRect(myOffScrHandle^^.blitRect,dh,dv);
- END
- ELSE IF (topSpace > dv) THEN {moving up}
- BEGIN
- dv := topSpace;
- OffsetRect(myOffScrHandle^^.blitRect,dh,dv);
- END
- ELSE
- OffsetRect(myOffScrHandle^^.blitRect,dh,dv);
-
- {Save actual distances moved to data structure.}
-
- WITH myOffScrHandle^^ DO
- BEGIN
- dhGraf := dhGraf + dh;
- dvGraf := dvGraf + dv;
- END;
- HUnlock(Handle(myOffScrHandle));
-
- {Shoot new contents of blit rectangle to screen.}
-
- DrawContents(theWindow);
- END; {ScrollContents}
-
-
- PROCEDURE MyScroll(theControl:ControlHandle;partCode:INTEGER);
-
- VAR
- myOffScrHandle: OffScrHandle;
- myScrollHandle: ScrollHandle;
- dh,dv: LONGINT;
- windowFull: LONGINT;
- myCtlValue: LONGINT;
- visHeight,visWidth: LONGINT;
- dontCare: LONGINT;
- tempDH,tempDV: LONGINT;
- startValue: INTEGER;
- myDocWidth,myDocHeight: INTEGER;
- direction: Str255;
- theWindow: WindowPtr;
-
- BEGIN
- theWindow := theControl^^.contrlOwner;
- myOffScrHandle := OffScrHandle(GetWRefCon(theWindow));
- MoveHHi(Handle(myOffScrHandle));
- HLock(Handle(myOffScrHandle));
-
- {Make local copies of data structure items.}
-
- WITH myOffScrHandle^^ DO
- BEGIN
- tempDH := dhGraf;
- tempDV := dvGraf;
- myDocWidth := docWidth;
- myDocHeight := docHeight;
- END;
- HUnlock(Handle(myOffScrHandle));
-
- {Initialize more variables for our formulas.}
-
- visHeight := theWindow^.portRect.bottom - 15 - theWindow^.portRect.top;
- visWidth := theWindow^.portRect.right - 15 - theWindow^.portRect.left;
- startValue := GetCtlValue(theControl);
- GetCTitle(theControl,direction);
- myScrollHandle := ScrollHandle(GetCRefCon(theControl));
- MoveHHi(Handle(myScrollHandle));
- HLock(Handle(myScrollHandle));
-
- {Implementation of two-speed, accelerating scroll bars.}
-
- WITH myScrollHandle^^ DO
- BEGIN
- heldDown := heldDown + 1;
- IF (heldDown > 2) THEN
- goFast := TRUE;
- END; {WITH}
-
- CASE partCode OF
- inUpButton:
- BEGIN
-
- {Don't scroll up if already at top!}
-
- IF (startValue > 0) THEN
- BEGIN
- IF (direction = 'MyVert') THEN
- BEGIN
- IF (visHeight >= myDocHeight) THEN
- BEGIN
- setCtlValue(theControl,0);
- ScrollContents(theWindow,0,-tempDV);
- END
- ELSE
- BEGIN
-
- {Scroll up five pixels}
-
- dv := tempDV - 5;
-
- {Set new thumb value using Golden Ratio.}
-
- myCtlValue := LONGINT((dv * myDocHeight) DIV (myDocHeight - visHeight));
- ClipRect(theWindow^.portRect);
- setCtlValue(theControl,INTEGER(myCtlValue));
-
- {Update blit rectangle, blast document to screen.}
-
- ScrollContents(theWindow,0,-5);
- END; {IF visHeight...ELSE}
- END
- ELSE
- BEGIN
-
- {Repeat for horizontal direction.}
-
- IF (visWidth >= myDocWidth) THEN
- BEGIN
- setCtlValue(theControl,0);
- ScrollContents(theWindow,-tempDH,0);
- END
- ELSE
- BEGIN
- dh := tempDH - 5;
- myCtlValue := LONGINT((dh * myDocWidth) DIV (myDocWidth - visWidth));
- ClipRect(theWindow^.portRect);
- setCtlValue(theControl,INTEGER(myCtlValue));
- ScrollContents(theWindow,-5,0);
- END; {IF visWidth...ELSE}
- END; {IF direction...ELSE}
- END; {IF startValue}
- IF (myScrollHandle^^.goFast = FALSE) THEN
- Delay(10,dontCare);
- END; {inUpButton}
-
- {Pattern is identical for down button, page up, and page down regions.}
-
- inDownButton:
- BEGIN
- IF (direction = 'MyVert') THEN
- BEGIN
- IF (startValue < myDocHeight) THEN
- BEGIN
- dv := tempDV + 5;
- myCtlValue := LONGINT((dv * myDocHeight) DIV (myDocHeight - visHeight));
- ClipRect(theWindow^.portRect);
- setCtlValue(theControl,INTEGER(myCtlValue));
- ScrollContents(theWindow,0,5);
- END; {IF startValue}
- END
- ELSE
- BEGIN
- IF (startValue < myDocWidth) THEN
- BEGIN
- dh := tempDH + 5;
- myCtlValue := LONGINT((dh * myDocWidth) DIV (myDocWidth - visWidth));
- ClipRect(theWindow^.portRect);
- setCtlValue(theControl,INTEGER(myCtlValue));
- ScrollContents(theWindow,5,0);
- END; {IF startValue}
- END; {IF direction... ELSE}
- IF (myScrollHandle^^.goFast = FALSE) THEN
- Delay(10,dontCare);
- END; {inDownButton}
-
- inPageUp:
- BEGIN
- IF (startValue > 0) THEN
- BEGIN
- IF (direction = 'MyVert') THEN
- BEGIN
- IF (visHeight >= myDocHeight) THEN
- BEGIN
- setCtlValue(theControl,0);
- ScrollContents(theWindow,0,-tempDV);
- END
- ELSE
- BEGIN
- windowFull := visHeight - 5;
- dv := tempDV - windowFull;
- IF (dv < 0) THEN
- dv := 0;
- myCtlValue := LONGINT((dv * myDocHeight) DIV (myDocHeight - visHeight));
- ClipRect(theWindow^.portRect);
- setCtlValue(theControl,INTEGER(myCtlValue));
- ScrollContents(theWindow,0,-windowFull);
- END; {IF visHeight...ELSE}
- END {IF direction}
- ELSE
- BEGIN
- IF (visWidth >= myDocWidth) THEN
- BEGIN
- setCtlValue(theControl,0);
- ScrollContents(theWindow,-tempDH,0);
- END
- ELSE
- BEGIN
- windowFull := visWidth - 5;
- dh := tempDH - windowFull;
- IF (dh < 0) THEN
- dh := 0;
- myCtlValue := LONGINT((dh * myDocWidth) DIV (myDocWidth - visWidth));
- ClipRect(theWindow^.portRect);
- setCtlValue(theControl,INTEGER(myCtlValue));
- ScrollContents(theWindow,-windowFull,0);
- END; {IF visWidth...ELSE}
- END; {IF direction... ELSE}
- IF (myScrollHandle^^.goFast = FALSE) THEN
- Delay(10,dontCare);
- END; {IF startValue}
- END; {inPageUp}
-
- inPageDown:
- BEGIN
- IF (direction = 'MyVert') THEN
- BEGIN
- IF (startValue < myDocHeight) THEN
- BEGIN
- windowFull := visHeight - 5;
- dv := tempDV + windowFull;
- myCtlValue := LONGINT((dv * myDocHeight) DIV (myDocHeight - visHeight));
- ClipRect(theWindow^.portRect);
- setCtlValue(theControl,INTEGER(myCtlValue));
- ScrollContents(theWindow,0,windowFull);
- END; {IF startValue}
- END {IF direction}
- ELSE
- BEGIN
- IF (startValue < myDocWidth) THEN
- BEGIN
- windowFull := visWidth - 5;
- dh := tempDH + windowFull;
- myCtlValue := LONGINT((dh * myDocWidth) DIV (myDocWidth - visWidth));
- ClipRect(theWindow^.portRect);
- setCtlValue(theControl,INTEGER(myCtlValue));
- ScrollContents(theWindow,windowFull,0);
- END; {IF startValue}
- END; {IF direction... ELSE}
- IF (myScrollHandle^^.goFast = FALSE) THEN
- Delay(10,dontCare);
- END; {inPageDown}
- END; {CASE partCode}
- HUnlock(Handle(myScrollHandle));
- ClipRect(theWindow^.portRect); {so TrackControl can unhilite arrows when mouse is released}
- END; {MyScroll}
-
-
- PROCEDURE Window(paramPtr:XCmdPtr);
-
- CONST
- minParamCount = 5;
- smallestHeight = 100;
- smallestWidth = 100;
- _WaitNextEvent = $A860;
- _Unimplemented = $A89F;
- active = 0;
- inactive = 255;
- MouseMovedEvt = $FA;
- SuspendResumeEvt = $01;
- SuspendEventMask = $1;
- ConvertScrapMask = $2;
- browseTool = 6069;
- HCWidth = 512;
- HCHeight = 342;
- padding = 16;
-
- VAR
- toolVis,patVis: BOOLEAN;
- msgVis,fatVis: BOOLEAN;
- hasWaitNextEvent: BOOLEAN;
- inBackGround,smallScreen: BOOLEAN;
- DoneFlag,HaveEvent: BOOLEAN;
- menuWasHidden: BOOLEAN;
- wTop,wLeft,wBottom,wRight: INTEGER;
- partCode,controlCode: INTEGER;
- largestHeight,largestWidth: INTEGER;
- dummy,charCode: INTEGER;
- screenWidth,screenHeight: INTEGER;
- myDocWidth,myDocHeight: INTEGER;
- eventPoint: Point;
- wRect,screenRect,dragRect: Rect;
- winSizeLimits: Rect;
- oldSize: Rect;
- newSize,dontCare: LONGINT;
- envError: OSErr;
- cursorRgn: RgnHandle;
- hScroll,vScroll: ControlHandle;
- whichControl: ControlHandle;
- myWindow,whichWindow: WindowPtr;
- fatBitsWindow: WindowPtr;
- HCrefresh: Str31;
- wT,wL,wB,wR,wTitle: Str255;
- toolStr,patStr,msgStr: Str255;
- widthStr,heightStr: Str255;
- myBits: BitMap;
- theEnv: SysEnvRec;
- myEvent: EventRecord;
- wRecord: WindowRecord;
- HCPort: GrafPtr;
- theOffScrHandle: OffScrHandle;
- theScrollHandle: ScrollHandle;
- myOffScr: OffScrRecord;
- myScrollRecord: ScrollRecord;
-
-
- FUNCTION TrapAvailable(tNumber: INTEGER; tType: TrapType):BOOLEAN;
-
- {Check to see if a given trap is implemented.}
-
- BEGIN
- TrapAvailable := NGetTrapAddress(tNumber, tType) <> GetTrapAddress(_Unimplemented);
- END; {TrapAvailable}
-
-
- FUNCTION CreateHScrollBar(theWindow:WindowPtr;theValue,theMin,theMax:INTEGER;theRefCon:LONGINT):ControlHandle;
- VAR
- myWindowRect,hScrRect : Rect;
-
- BEGIN
- SetPort(theWindow);
- myWindowRect := theWindow^.portRect;
- SetRect(hScrRect,myWindowRect.left -1,
- myWindowRect.bottom - 15,
- myWindowRect.right - 14,
- myWindowRect.bottom + 1);
- CreateHScrollBar := NewControl(theWindow,hScrRect,'MyHoriz',TRUE,
- theValue,theMin,theMax,scrollBarProc,theRefCon);
- END; {CreateHScrollBar}
-
-
- FUNCTION CreateVScrollBar(theWindow:WindowPtr;theValue,theMin,theMax:INTEGER;theRefCon:LONGINT):ControlHandle;
- VAR
- myWindowRect,hScrRect : Rect;
-
- BEGIN
- SetPort(theWindow);
- myWindowRect := theWindow^.portRect;
- SetRect(hScrRect,myWindowRect.right -15,
- myWindowRect.top - 1,
- myWindowRect.right + 1,
- myWindowRect.bottom - 14);
- CreateVScrollBar := NewControl(theWindow,hScrRect,'MyVert',TRUE,
- theValue,theMin,theMax,scrollBarProc,theRefCon);
- END; {CreateVScrollBar}
-
-
- PROCEDURE InvalScroll(theWindow:WindowPtr);
- VAR
- theRect,tallRect,wideRect : Rect;
-
- BEGIN
- SetPort(theWindow);
- theRect := theWindow^.portRect;
- ClipRect(theRect);
-
- { Accumulate tallRect, which is occupied by the vertical scroll bar }
-
- SetRect(tallRect,theRect.right-15,
- theRect.top,
- theRect.right,
- theRect.bottom);
- EraseRect(tallRect);
- InvalRect(tallRect);
-
- { Accumulate wideRect, which is occupied by the horizontal scroll bar }
-
- SetRect(wideRect,theRect.left,
- theRect.bottom-15,
- theRect.right,
- theRect.bottom);
- EraseRect(wideRect);
- InvalRect(wideRect);
- END; {InvalScroll}
-
-
- PROCEDURE Deactivate(theWindow:WindowPtr);
-
- {Deactivate the scroll bars in theWindow in accordance
- with the human interface guidelines. This means we must
- erase everything enclosed by the control rectangles.}
-
- VAR
- theControl: ControlHandle;
- theControlRect: Rect;
-
- BEGIN
-
- {I always title my scroll bars 'MyVert' and 'MyHoriz'
- so I can easily find them by walking the window's
- control list.}
-
- theControl := WindowPeek(theWindow)^.controlList;
- WHILE (theControl <> NIL) DO
- BEGIN
- IF (theControl^^.contrlTitle = 'MyVert') OR
- (theControl^^.contrlTitle = 'MyHoriz') THEN
- BEGIN
- theControlRect := theControl^^.contrlRect;
- InsetRect(theControlRect,1,1);
- EraseRect(theControlRect);
- END; {IF}
- theControl := theControl^^.nextControl;
- END; {WHILE}
- END; {Deactivate}
-
-
- PROCEDURE HiliteScrollBars(theWindow:WindowPtr);
-
- VAR
- myWindowRect: Rect;
- visWidth,visHeight: INTEGER;
- myDocWidth,myDocHeight: INTEGER;
- myCtlValue: INTEGER;
- tempDH,tempDV: LONGINT;
- myOffScrHandle: OffScrHandle;
-
- BEGIN
- myOffScrHandle := OffScrHandle(GetWRefCon(theWindow));
- MoveHHi(Handle(myOffScrHandle));
- HLock(Handle(myOffScrHandle));
-
- {Make local copies of data structure items.}
-
- WITH myOffScrHandle^^ DO
- BEGIN
- tempDH := dhGraf;
- tempDV := dvGraf;
- myDocWidth := docWidth;
- myDocHeight := docHeight;
- END;
-
- HUnlock(Handle(myOffScrHandle));
- myWindowRect := theWindow^.portRect;
- visHeight := myWindowRect.bottom - 15 - myWindowRect.top;
- visWidth := myWindowRect.right - 15 - myWindowRect.left;
- SetPort(theWindow);
- ClipRect(myWindowRect);
-
- { Check to see if window is taller than contents. If
- so, unhilite vertical scroll bar. Otherwise, use
- Golden Ratio to draw vertical scroll bar with thumb
- in right position. }
-
- IF ((visHeight >= myDocHeight) AND (tempDV = 0)) THEN
- HiliteControl(vScroll,INTEGER(inactive))
- ELSE
- BEGIN
- HiliteControl(vScroll,INTEGER(active));
- IF (visHeight >= myDocHeight) THEN
- SetCtlValue(vScroll,myDocHeight)
- ELSE
- BEGIN
- myCtlValue := LONGINT((tempDV * myDocHeight) DIV (myDocHeight - visHeight));
- ClipRect(theWindow^.portRect);
- setCtlValue(vScroll,INTEGER(myCtlValue));
- END; {IF visHeight...ELSE}
- END;
-
- { Repeat for horizontal scroll bar. }
-
- IF ((visWidth >= myDocWidth) AND (tempDH = 0)) THEN
- HiliteControl(hScroll,INTEGER(inactive))
- ELSE
- BEGIN
- HiliteControl(hScroll,INTEGER(active));
- IF (visWidth >= myDocWidth) THEN
- SetCtlValue(hScroll,myDocWidth)
- ELSE
- BEGIN
- myCtlValue := LONGINT((tempDH * myDocWidth) DIV (myDocWidth - visWidth));
- ClipRect(theWindow^.portRect);
- setCtlValue(hScroll,INTEGER(myCtlValue));
- END; {IF visWidth...ELSE}
- END;
-
- END; {HiliteScrollBars}
-
-
- PROCEDURE MoveScrollBars(theWindow:WindowPtr);
-
- VAR
- myWindowRect: Rect;
- vScrRect,hScrRect: Rect;
-
- BEGIN
- myWindowRect := theWindow^.portRect;
- SetRect(hScrRect,myWindowRect.left - 1,
- myWindowRect.bottom - 15,
- myWindowRect.right - 14,
- myWindowRect.bottom + 1);
- SetRect(vScrRect,myWindowRect.right - 15,
- myWindowRect.top - 1,
- myWindowRect.right + 1,
- myWindowRect.bottom - 14);
- SetPort(theWindow);
- ClipRect(myWindowRect);
-
- { Hide and resize the scroll bars to fit the new window size. }
-
- HideControl(hScroll);
- HideControl(vScroll);
- MoveControl(hScroll,hScrRect.left,hScrRect.top);
- SizeControl(hScroll,(hScrRect.right - hScrRect.left),
- (hScrRect.bottom - hScrRect.top));
- MoveControl(vScroll,vScrRect.left,vScrRect.top);
- SizeControl(vScroll,(vScrRect.right - vScrRect.left),
- (vScrRect.bottom - vScrRect.top));
- HiliteScrollBars(theWindow);
- ShowControl(hScroll);
- ShowControl(vScroll);
- END; {MoveScrollBars}
-
-
- PROCEDURE ScrollWithThumb(theControl:ControlHandle;theEventPoint:Point);
-
- VAR
- theWindow: WindowPtr;
- myOffScrHandle: OffScrHandle;
- visWidth,visHeight: INTEGER;
- myDocWidth,myDocHeight: INTEGER;
- startValue,endValue: INTEGER;
- dummy: INTEGER;
- amountToScroll: LONGINT;
- tempDH,tempDV: LONGINT;
- direction: Str255;
-
- BEGIN
- theWindow := theControl^^.contrlOwner;
- myOffScrHandle := OffScrHandle(GetWRefCon(theWindow));
- MoveHHi(Handle(myOffScrHandle));
- HLock(Handle(myOffScrHandle));
-
- {Make local copies of data structure items.}
-
- WITH myOffScrHandle^^ DO
- BEGIN
- tempDH := dhGraf;
- tempDV := dvGraf;
- myDocWidth := docWidth;
- myDocHeight := docHeight;
- END;
- HUnlock(Handle(myOffScrHandle));
- GetCTitle(theControl,direction);
- visHeight := theWindow^.portRect.bottom -
- theWindow^.portRect.top - 15;
- visWidth := theWindow^.portRect.right -
- theWindow^.portRect.left - 15;
-
- {Record where thumb is before it is moved.}
-
- startValue := GetCtlValue(theControl);
-
- {Move it.}
-
- dummy := TrackControl(theControl,theEventPoint,NIL);
-
- {Record where thumb is released.}
-
- endValue := GetCtlValue(theControl);
-
- {Record the distance thumb was moved.}
-
- amountToScroll := LONGINT(endValue - startValue);
- IF (direction = 'MyVert') THEN
- BEGIN {moved vertical scroll bar}
- IF (endValue = 0) THEN {moved thumb to top}
- ScrollContents(theWindow,0,-tempDV)
- ELSE
- IF (endValue = myDocHeight) THEN {moved thumb to bottom}
- ScrollContents(theWindow,0,myDocHeight - tempDV)
- ELSE
- BEGIN
- {moved thumb somewhere in middle - use Golden Ratio to
- translate thumb movement into document movement.}
- amountToScroll := LONGINT((amountToScroll *
- (myDocHeight - visHeight)) DIV
- myDocHeight);
- IF (ABS(amountToScroll) < 1) THEN
- {didn't move thumb far enough to scroll - snap it
- back to starting position.}
- SetCtlValue(theControl,startValue)
- ELSE
- ScrollContents(theWindow,0,INTEGER(amountToScroll));
- END;
- END
- ELSE {moved horizontal scroll bar}
- BEGIN
- IF (endValue = 0) THEN
- ScrollContents(theWindow,-tempDH,0)
- ELSE
- IF (endValue = myDocWidth) THEN
- ScrollContents(theWindow,myDocWidth - tempDH,0)
- ELSE
- BEGIN
- amountToScroll := LONGINT((amountToScroll *
- (myDocWidth - visWidth)) DIV
- myDocWidth);
- IF (ABS(amountToScroll) < 1) THEN
- SetCtlValue(theControl,startValue)
- ELSE
- ScrollContents(theWindow,INTEGER(amountToScroll),0);
- END;
- END;
- END; {ScrollWithThumb}
-
-
- FUNCTION WhichDevice(thePoint:Point):GDHandle;
-
- VAR
- aDevice: GDHandle;
- foundOne: BOOLEAN;
-
- BEGIN
- aDevice := GetDeviceList;
- foundOne := FALSE;
-
- WHILE (aDevice <> NIL) AND NOT foundOne DO
- BEGIN
- IF PtInRect(thePoint,aDevice^^.gdRect) THEN
- BEGIN
- WhichDevice := aDevice;
- foundOne := TRUE;
- END;
- aDevice := aDevice^^.gdNextGD;
- END;
- END; { WhichDevice }
-
-
- FUNCTION MenuBarHeight: INTEGER;
-
- {Returns the height of the menubar in pixels, as
- read from the low memory global mBarHeight.}
-
- CONST
- mBarHeight = $BAA;
-
- VAR
- menuBarHeightPtr: ^INTEGER;
-
- BEGIN
- menuBarHeightPtr := Pointer(mBarHeight);
- MenuBarHeight := menuBarHeightPtr^;
- END; {MenuBarHeight}
-
-
- FUNCTION OnAScreen(theRect:Rect):BOOLEAN;
-
- CONST
- titleBarHeight = 18;
-
- VAR
- deskRgn: RgnHandle;
- topLeft,topRight: Point;
-
- BEGIN
- deskRgn := GetGrayRgn;
- topLeft.v := theRect.top - titleBarHeight;
- topLeft.h := theRect.left + titleBarHeight;
- topRight.v := topLeft.v;
- topRight.h := theRect.right - titleBarHeight;
- IF ((PtInRgn(topLeft,deskRgn)) OR (PtInRgn(topRight,deskRgn))) THEN
- OnAScreen := TRUE
- ELSE
- OnAScreen := FALSE;
- END; {OnAScreen}
-
-
- PROCEDURE ZoomIt(theWindow:WindowPtr;partCode:INTEGER;clickedWhere:Point);
-
- CONST
- titleBarHeight = 18;
-
- TYPE
- WStatePtr = ^WStateData;
- WStateHandle = ^WStatePtr;
-
- VAR
- oldRect,newRect: Rect;
- maxHeight: INTEGER;
-
- BEGIN
- oldRect := theWindow^.portRect;
- IF theEnv.hasColorQD THEN
- BEGIN
- newRect := WhichDevice(clickedWhere)^^.gdRect;
- IF WhichDevice(clickedWhere) = GetMainDevice THEN
- BEGIN
- newRect.top := newRect.top + MenuBarHeight;
- END;
- END
- ELSE
- newRect := GetGrayRgn^^.rgnBBox;
- newRect.left := newRect.left + 2;
- newRect.top := newRect.top + titleBarHeight + 2;
- newRect.right := newRect.right - 3;
- newRect.bottom := newRect.bottom - 3;
- IF NOT EqualRect(oldRect,newRect) THEN
- WITH WindowPeek(theWindow)^ DO
- WStateHandle(dataHandle)^^.stdState := newRect;
- SetPort(theWindow);
- EraseRect(whichWindow^.portRect);
- InvalRect(whichWindow^.portRect);
- ZoomWindow(theWindow,partcode,FALSE);
- END; { ZoomIt }
-
-
- {$I XCmdGlue.inc}
-
-
- PROCEDURE Fail(errStr:Str255);
-
- {Fail returns errStr to HyperCard and exits the XCMD.
- errStr can then be checked by inspecting HyperCard's
- global variable "the result." See "XCMD's for Hyper-
- Card" by Gary Bond (MIS Press, 1988) for more details.
-
- © 1988 by Gary Bond
- All rights reserved.
- You may use this code for NON-COMMERCIAL purposes.}
-
- BEGIN
- paramPtr^.returnValue := PasToZero(errStr);
- SysBeep(1);
- EXIT(Window);
- END; {Fail}
-
-
- PROCEDURE CheckParamCount;
-
- {CheckParamCount sees if the number of parameters
- passed to the XCMD matches the number expected. If
- not, we exit from the XCMD with an error message.
- See "XCMD's for HyperCard" by Gary Bond (MIS Press,
- 1988) for more details.
-
- © 1988 by Gary Bond
- All rights reserved.
- You may use this code for NON-COMMERCIAL purposes.}
-
- VAR
- numParams : INTEGER;
-
- BEGIN
- numParams := paramPtr^.paramCount;
- IF(numParams <> minParamCount) THEN
- Fail('Form: HyperWindow "Window Title",top,left,bottom,right');
- END; {CheckParamCount}
-
-
- FUNCTION GetHCVersion:Str255;
-
- {Return a string containing the version of HyperCard
- being used; e.g., '1.2'}
-
- BEGIN
- ZeroToPas(EvalExpr('the version')^,GetHCVersion);
- END;
-
-
- PROCEDURE HideWindoids;
-
- {Get and save the visible state of the tool, pattern,
- message and fatbits windoids; then hide them if they
- are showing.}
-
- VAR
- toolH,patH,msgH,fatH: Handle;
-
- PROCEDURE HideFatBits;
-
- {HyperCard does not have a built-in command for hiding
- and showing the fatbits windoid, so we have to do it
- ourselves. HideFatBits walks the window list until it
- finds a window with title "FatBits," then hides it if
- the visible field of its WindowRecord is true.
- HideFatBits also saves the WindowPtr to the fatbits
- windoid so we can use it later (e.g., to show the
- windoid again).}
-
- CONST
- windowList = $9D6; {Low memory global location.}
-
- VAR
- theWindow: WindowPeek;
- theWindowPtr: ^WindowPtr;
-
- BEGIN
- theWindowPtr := Pointer(windowList);
- theWindow := WindowPeek(theWindowPtr^);
- fatVis := FALSE;
- WHILE (theWindow <> NIL) DO
- BEGIN
- IF (theWindow^.titleHandle^^ = 'FatBits') THEN
- BEGIN
- fatBitsWindow := WindowPtr(theWindow);
- IF (theWindow^.visible = TRUE) THEN
- BEGIN
- fatVis := TRUE;
- HideWindow(fatBitsWindow);
- theWindow := NIL;
- END;
- END;
- IF (theWindow <> NIL) THEN
- theWindow := WindowPeek(theWindow)^.nextWindow;
- END; {WHILE}
- END; {HideFatBits}
-
- BEGIN {HideWindoids}
-
- {Get visible state of windoids.}
-
- toolH := EvalExpr('visible of tool window');
- ZeroToPas(toolH^,toolStr);
- DisposHandle(toolH);
- toolVis := StrToBool(toolStr);
-
- patH := EvalExpr('visible of pattern window');
- ZeroToPas(patH^,patStr);
- DisposHandle(patH);
- patVis := StrToBool(patStr);
-
- msgH := EvalExpr('visible of message window');
- ZeroToPas(msgH^,msgStr);
- DisposHandle(msgH);
- msgVis := StrToBool(msgStr);
-
- {Hide the ones that are showing.}
-
- HideFatBits;
-
- IF toolVis THEN
- SendHCMessage('hide tool window');
- IF patVis THEN
- SendHCMessage('hide pattern window');
- IF msgVis THEN
- SendHCMessage('hide message window');
- END; {HideWindoids}
-
-
- PROCEDURE ShowWindoids;
-
- {This routine assumes HideWindoids has been called
- before. ShowWindoids restores the visible state of
- the windoids to that saved by HideWindoids.}
-
- BEGIN
- IF toolVis THEN
- SendHCMessage('show tool window');
- IF patVis THEN
- SendHCMessage('show pattern window');
- IF msgVis THEN
- SendHCMessage('show message window');
-
- {As in HideWindoids, we must take care of the FatBits
- windoid ourselves.}
-
- IF fatVis THEN
- BEGIN
- ShowWindow(fatBitsWindow);
- SelectWindow(fatBitsWindow);
- END;
- END; {ShowWindoids}
-
-
- PROCEDURE ToggleMenuBar;
-
- {Set the visible of the menubar to not the visible of
- the menubar.}
-
- BEGIN
- IF MenuBarHeight = 0 THEN
- SendHCMessage('show menuBar')
- ELSE
- SendHCMessage('hide menuBar');
- END; {ToggleMenuBar}
-
-
- PROCEDURE GetHCBitMap;
-
- VAR
- myDocHeight,myDocWidth: INTEGER;
- HCRect,myHCRect: Rect;
- dummyGrafPtr: GrafPtr;
- HCBits: BitMap;
-
- BEGIN
- MoveHHi(Handle(theOffScrHandle));
- HLock(Handle(theOffScrHandle));
- WITH theOffScrHandle^^ DO
- BEGIN
- myDocWidth := docWidth;
- myDocHeight := docHeight;
- END;
- myBits.rowBytes := (((myDocWidth - 1) DIV 16) + 1) * 2;
- myBits.baseAddr := NewPtr(myBits.rowBytes * myDocHeight);
- IF (myBits.baseAddr = NIL) THEN
- Fail('Could not allocate bitmap.');
- HCRect := HCPort^.portRect;
- HCBits := HCPort^.portBits;
- SetRect(myBits.bounds,0,
- 0,
- 528,
- 358);
-
- dummyGrafPtr := GrafPtr(NewPtr(sizeOf(GrafPort)));
- IF (dummyGrafPtr = NIL) THEN
- BEGIN
- DisposPtr(myBits.baseAddr);
- Fail('Could not allocate offscreen grafPort.');
- END;
- theOffScrHandle^^.gPort := dummyGrafPtr;
- OpenPort(theOffScrHandle^^.gPort);
- SetOrigin(0,0);
- SetPortBits(myBits);
- MovePortTo(0,0);
- PortSize(myDocWidth,myDocHeight);
- RectRgn(theOffScrHandle^^.gPort^.visRgn,theOffScrHandle^^.gPort^.portRect);
- RectRgn(theOffScrHandle^^.gPort^.clipRgn,theOffScrHandle^^.gPort^.portRect);
- EraseRect(theOffScrHandle^^.gPort^.portRect);
- SetRect(myHCRect,0,
- 0,
- 512,
- 342);
- CopyBits(HCBits,theOffScrHandle^^.gPort^.portBits,HCRect,myHCRect,srcCopy,NIL);
- HUnlock(Handle(theOffScrHandle));
- END; {GetHCBitMap}
-
-
- PROCEDURE AdjustCursor;
-
- {AdjustCursor changes cursorRgn to the region that contains
- the cursor. As soon as the cursor moves out of cursorRgn, we
- get an event and can change the cursor and cursorRgn again.
- cursorRgn is either the content region of our window or
- the region containing everything BUT the content region of our
- window.}
-
- VAR
- mousePt: Point;
- myWinContRect: Rect;
- myWinContRgn: RgnHandle;
- deskRgn: RgnHandle;
- handHdl: CursHandle;
-
- BEGIN
- SetPort(myWindow);
- GetMouse(mousePt);
- LocalToGlobal(mousePt);
- myWinContRgn := NewRgn;
-
- {Calculate the "work region" of our window, which is its
- content region minus the scroll bars and grow icon. This
- is the region within which we want the cursor to change
- to a cross, and outside of which we want it to be an arrow.}
-
- WITH WindowPeek(myWindow)^.contRgn^^.rgnBBox DO
- SetRect(myWinContRect,left, top, right - 15, bottom - 15);
- RectRgn(myWinContRgn,myWinContRect);
-
- IF PtInRect(mousePt,myWinContRect) THEN
- BEGIN
-
- {The cursor is in the work region of our window}
-
- handHdl := GetCursor(browseTool);
- IF (handHdl <> NIL) THEN
- SetCursor(handHdl^^)
- ELSE
- InitCursor;
-
- {Set the cursor region equal to our window's work region.}
-
- SetEmptyRgn(cursorRgn);
- CopyRgn(myWinContRgn,cursorRgn);
- END
- ELSE
- BEGIN
-
- {The cursor is outside our window.}
-
- InitCursor;
-
- {Get the current desktop region}
-
- deskRgn := GetGrayRgn;
-
- {Set cursorRgn to the desktop region's bounding box. It is
- important to add the menu bar area to cursorRgn too.}
-
- SetRectRgn(cursorRgn, deskRgn^^.rgnBBox.left,
- deskRgn^^.rgnBBox.top,
- deskRgn^^.rgnBBox.right,
- deskRgn^^.rgnBBox.bottom);
-
- {Punch out our window's content region from the big region}
-
- DiffRgn(cursorRgn,myWinContRgn,cursorRgn);
- END;
- DisposeRgn(myWinContRgn);
- END; {AdjustCursor}
-
-
- BEGIN {Main Program}
-
- {Check the HyperCard version. Must be 1.2 or greater.}
-
- IF GetHCVersion < '1.2' THEN
- Fail('Sorry, must have HyperCard 1.2 or greater.');
-
- {Save thy grafPort upon entering!}
-
- GetPort(HCPort);
-
- {Check and reset our environment.}
-
- CheckParamCount;
- FlushEvents(everyEvent,0);
- InitCursor;
-
- { Find out what kind of machine we're running on }
-
- envError := SysEnvirons(1,theEnv);
- IF (envError <> noErr) THEN
- Fail('SysEnvirons call failed.');
-
- { Convert HyperTalk input parameters for use here }
-
- ZeroToPas(paramPtr^.params[1]^,wTitle);
- ZeroToPas(paramPtr^.params[2]^,wT);
- ZeroToPas(paramPtr^.params[3]^,wL);
- ZeroToPas(paramPtr^.params[4]^,wB);
- ZeroToPas(paramPtr^.params[5]^,wR);
-
- wTop := INTEGER(StrToNum(wT));
- wLeft := INTEGER(StrToNum(wL));
- wBottom := INTEGER(StrToNum(wB));
- wRight := INTEGER(StrToNum(wR));
-
- {If window size parameters are too small or illegal, set
- the window to a predefined minimum size.}
-
- IF ((wRight - wLeft) < smallestWidth) THEN
- wRight := wLeft + smallestWidth;
- IF ((wBottom - wTop) < smallestHeight) THEN
- wBottom := wTop + smallestHeight;
-
- {Make sure the user is not trying to draw the window off
- the screen or under the menubar.}
-
- SetRect(wRect,wLeft,wTop,wRight,wBottom);
- IF NOT OnAScreen(wRect) THEN
- Fail('You are trying to draw your window off the screen!');
-
- {Get the bounds of the desktop.}
-
- screenRect := GetGrayRgn^^.rgnBBox;
-
- {If we have a small screen, make a note of it so we can hide the
- card window during context switches under MultiFinder.}
-
- ZeroToPas(EvalExpr('item 3 of the screenRect')^,widthStr);
- screenWidth := INTEGER(StrToNum(widthStr));
- ZeroToPas(EvalExpr('item 4 of the screenRect')^,heightStr);
- screenHeight := INTEGER(StrToNum(heightStr));
-
- IF (screenWidth = 512) AND (screenHeight = 342) THEN
- smallScreen := TRUE
- ELSE
- smallScreen := FALSE;
-
- HideWindoids;
-
- IF MenuBarHeight > 0 THEN
- menuWasHidden := FALSE
- ELSE
- menuWasHidden := TRUE;
-
- theOffScrHandle := OffScrHandle(NewHandle(SizeOf(OffScrRecord)));
- IF MemError <> noErr THEN
- Fail('Out of memory. Buy more.');
-
- myDocWidth := HCWidth + padding;
- myDocHeight := HCHeight + padding;
-
- MoveHHi(Handle(theOffScrHandle));
- HLock(Handle(theOffScrHandle));
- WITH theOffScrHandle^^ DO
- BEGIN
- docWidth := myDocWidth;
- docHeight := myDocHeight;
- END;
- HUnlock(Handle(theOffScrHandle));
-
- GetHCBitMap;
-
- myWindow := NewWindow(@wRecord,wRect,wTitle,TRUE,zoomDocProc,
- WindowPtr(-1),TRUE,1);
- IF (myWindow = NIL) THEN
- BEGIN
- DisposPtr(myBits.baseAddr);
- ClosePort(myOffScr.gPort);
- DisposPtr(Ptr(myOffScr.gPort));
- ShowWindoids;
- Fail('Not enough memory to draw window.');
- END
- ELSE
- BEGIN
- SetWRefCon(myWindow,LONGINT(theOffScrHandle));
- InitBlit(myWindow);
- DrawGrowIcon(myWindow);
- theScrollHandle := ScrollHandle(NewHandle(SizeOf(ScrollRecord)));
- IF MemError <> noErr THEN
- Fail('Out of memory. Buy more.');
- theScrollHandle^^.heldDown := 0;
- theScrollHandle^^.goFast := FALSE;
-
- {Draw horizontal and vertical scroll bars in our
- window.}
-
- hScroll := CreateHScrollBar(myWindow,0,0,myDocWidth,LONGINT(theScrollHandle));
- vScroll := CreateVScrollBar(myWindow,0,0,myDocHeight,LONGINT(theScrollHandle));
- HiliteScrollBars(myWindow);
- DrawContents(myWindow);
- SetRect(dragRect,screenRect.left + 4,
- screenRect.top,
- screenRect.right - 4,
- screenRect.bottom - 4);
- largestHeight := screenRect.bottom - screenRect.top;
- largestWidth := screenRect.right - screenRect.left;
- SetRect(winSizeLimits,smallestWidth,
- smallestHeight,
- largestWidth,
- largestHeight);
-
- HCRefresh := 'Go to this card';
- cursorRgn := NewRgn;
- inBackGround := FALSE;
- DoneFlag := FALSE;
- REPEAT
-
- {Call WaitNextEvent, if available. Otherwise call
- GetNextEvent.}
-
- IF hasWaitNextEvent THEN
- HaveEvent := WaitNextEvent(everyEvent,myEvent,15,cursorRgn)
- ELSE
- BEGIN
- HaveEvent := GetNextEvent(everyEvent,myEvent);
- AdjustCursor;
- END;
- IF HaveEvent THEN
- BEGIN
- IF (myEvent.what = app4Evt) THEN
-
- {Pre-process app4Evt's fed to us by MultiFinder.}
-
- CASE BSR(myEvent.message,24) OF
-
- MouseMovedEvt:
- AdjustCursor;
-
- SuspendResumeEvt:
- BEGIN
- myEvent.what := activateEvt;
-
- { Resume event }
-
- IF (BAND(myEvent.message,SuspendEventMask) <> 0) THEN
- inBackground := FALSE
- ELSE
-
- { Suspend event }
-
- inBackground := TRUE;
-
- myEvent.message := LONGINT(myWindow);
- END; {SuspendResumeEvt}
-
- END; {CASE BSR}
- END; {IF HaveEvent}
-
- CASE myEvent.what OF
-
- mouseDown:
- BEGIN
- partCode := FindWindow(myEvent.where,whichWindow);
- IF (whichWindow = myWindow) THEN
- BEGIN
-
- {Deal with mouse hits to our window.}
-
- CASE partCode OF
-
- inDrag:
- BEGIN
- SelectWindow(whichWindow); {DragWindow bug}
- DragWindow(whichWindow,myEvent.where,dragRect);
- SendCardMessage(HCrefresh);
- AdjustCursor;
- END;
-
- inGrow:
- BEGIN
- IF StillDown THEN {GrowWindow bug}
- BEGIN
- oldSize := whichWindow^.portRect;
- newSize := GrowWindow(whichWindow,myEvent.where,winSizeLimits);
- IF (newSize <> 0) THEN
- BEGIN
- InvalScroll(whichWindow);
- SizeWindow(whichWindow,LOWORD(newSize),HIWORD(newSize),FALSE);
- InvalContents(whichWindow,oldSize);
- DrawGrowIcon(whichWindow);
- MoveScrollBars(whichWindow);
- END; {IF newSize}
- END; {IF StillDown}
- END; {inGrow}
-
- inZoomIn,inZoomOut:
- BEGIN
- IF (TrackBox(whichWindow,myEvent.where,partCode)) THEN
- BEGIN
- InvalScroll(whichWindow);
- ZoomIt(whichWindow,partCode,myEvent.where);
- InvalContents(whichWindow,oldSize);
- DrawGrowIcon(whichWindow);
- MoveScrollBars(whichWindow);
- END;
- END;
-
- inContent:
- BEGIN
- SetPort(whichWindow);
- eventPoint := myEvent.where;
- GlobalToLocal(eventPoint);
- controlCode := FindControl(eventPoint,whichWindow,whichControl);
- ClipRect(whichWindow^.portRect);
- IF (controlCode = inThumb) THEN
- ScrollWithThumb(whichControl,eventPoint)
- ELSE
- BEGIN
- IF (controlCode <> 0) THEN
- BEGIN
- WITH ScrollHandle(whichControl^^.contrlRfCon)^^ DO
- BEGIN
- heldDown := 0;
- goFast := FALSE;
- END;
- dummy := TrackControl(whichControl,eventPoint,@MyScroll);
- END; {IF controlCode}
- END; {IF controlCode}
- END; {inContent}
-
- inGoAway:
- BEGIN
- IF(TrackGoAway(whichWindow,myEvent.where)) THEN
- DoneFlag := TRUE;
- END;
-
- END; {CASE partCode}
- END
- ELSE
- BEGIN
- IF MenuBarHeight > 0 THEN
- BEGIN
- FlashMenuBar(0);
- Delay(LONGINT(6),dontCare);
- FlashMenuBar(0);
- END; {IF MenuBarHeight}
- END; {IF FindWindow...ELSE}
- END; {mouseDown}
-
- activateEvt:
- BEGIN
- IF(WindowPtr(myEvent.message) = myWindow) THEN
- BEGIN
- SetPort(myWindow);
- ClipRect(myWindow^.portRect);
- DrawGrowIcon(myWindow);
- IF inBackground THEN
- BEGIN
-
- {We've been sent behind another application
- under MultiFinder, so deactivate the scroll
- bars and show the menubar if it was hidden.}
-
- Deactivate(myWindow);
- IF smallScreen THEN
- ShowHide(WindowPtr(HCPort),FALSE);
- IF MenuBarHeight = 0 THEN
- BEGIN
- SendHCMessage('show menubar');
- menuWasHidden := TRUE;
- END
- ELSE
- menuWasHidden := FALSE;
- END
- ELSE
- BEGIN
-
- {We've been brought to the front under Multi-
- Finder, so reactivate the scroll bars and
- hide the menubar if it was hidden before.}
-
- ShowHide(WindowPtr(HCPort),TRUE);
- IF menuWasHidden THEN
- SendHCMessage('hide menubar');
- DrawControls(myWindow);
- HiliteScrollBars(myWindow);
- FlushEvents(everyEvent,0);
- END; {IF inBackground}
- END; {IF WindowPtr}
- END; {activateEvt}
-
- updateEvt:
- BEGIN
-
- {Handle updates to our window.}
-
- IF(WindowPtr(myEvent.message) = myWindow) THEN
- BEGIN
-
- {Always do this stuff}
-
- SetPort(myWindow);
- BeginUpdate(myWindow);
- ClipRect(myWindow^.portRect);
- DrawGrowIcon(myWindow);
-
- {Always do this stuff under single Finder but
- only if in foreground under MultiFinder}
-
- IF NOT inBackground THEN
- BEGIN
- HiliteScrollBars(myWindow);
- DrawControls(myWindow);
- AdjustCursor;
- END;
-
- {Always do this stuff}
-
- DrawContents(myWindow);
- EndUpdate(myWindow);
- END {IF myEvent.message}
-
- {Handle updates to HyperCard's card window.}
-
- ELSE IF (WindowPtr(myEvent.message) = WindowPtr(HCPort)) THEN
- BEGIN
- SendHCMessage(HCRefresh);
-
- {Must zero out card window's update region
- ourselves because the SendHCMessage call
- doesn't do it, and we'll wind up in an
- infinite loop if we don't.}
-
- BeginUpdate(WindowPtr(HCPort));
- EndUpdate(WindowPtr(HCPort));
- END; {IF... ELSE}
- END; {updateEvt}
-
- keyDown:
- BEGIN
- IF(BitAnd(myEvent.modifiers,cmdKey) <> 0) THEN
- BEGIN
- charCode := BitAnd(myEvent.message,charCodeMask);
-
- {Pressing command-spacebar toggles the menubar.}
-
- IF(CHR(charCode) = ' ') THEN
- ToggleMenuBar
-
- {Pressing command-W closes the window and exits
- the XCMD.}
-
- ELSE IF(CHR(charCode) = 'w') THEN
- DoneFlag := True;
- END;
- END;
- END; {CASE myEvent.what}
-
- UNTIL (DoneFlag = True);
-
- {Clean up and get outta here!}
-
- DisposeRgn(cursorRgn);
- DisposPtr(myBits.baseAddr);
- ClosePort(theOffScrHandle^^.gPort);
- DisposPtr(Ptr(theOffScrHandle^^.gPort));
- DisposHandle(Handle(theOffScrHandle));
- DisposHandle(Handle(theScrollHandle));
- CloseWindow(myWindow);
- SendCardMessage(HCrefresh);
- ShowWindoids;
- InitCursor;
- FlushEvents(everyEvent,0);
-
- {Restore thy grafPort}
-
- SetPort(HCPort);
- END; {IF myWindow...ELSE}
- END; {Main}
- END. {Window}